﻿using System;
using System.Collections.Generic;
using System.Linq;
using OS.Infrastructure.Domain.UnitOfWork;
using TaskKernel.DTO;
using TaskKernel.Domain;
using TaskKernel.Domain.Interface;
using TaskKernel.Domain.Nhibernate.NHibernateLayer;
using TaskKernel.Domain.Services.Action;

namespace TaskWebApplicationUI.PresenterLayer
{
    public class AllTaskPresenter : AbstractPresenter<IListTaskView>
    {
        private readonly IDepartmentService _departmentService;
        private readonly IQueryAccount _queryAccount;
        private readonly IQueryDepartment _queryDepartment;
        private readonly IUnitOfWorkFactory _uow;
        private Account _currentAccount;
        private Department _currentDepartment;
        private IList<ExecutorsModel> _executorsModels;

        public AllTaskPresenter(IQueryDepartment queryDepartment, IQueryAccount queryAccount,
                                IDepartmentService departmentService, IUnitOfWorkFactory uow)
        {
            _queryDepartment = queryDepartment;
            _queryAccount = queryAccount;
            _departmentService = departmentService;
            _uow = uow;
            _executorsModels = new List<ExecutorsModel>();
        }

        private Account CurrentAccount
        {
            get
            {
                if (_currentAccount != null)
                    return _currentAccount;
                if (!String.IsNullOrEmpty(View.LogonUser)){
                    _currentAccount = _queryAccount.Get(View.LogonUser);
                    if (_currentAccount != null)
                        return _currentAccount;
                }
                throw new NotImplementedException("Don't know who are you...");
            }
        }

        private Department CurrentDepartment
        {
            get
            {
                if (_currentDepartment != null)
                    return _currentDepartment;
                if (!String.IsNullOrEmpty(View.WebPath)){
                    _currentDepartment = _queryDepartment.GetDepartmentByWebPath(View.WebPath);
                    if (_currentDepartment != null)
                        return _currentDepartment;
                    if (_queryDepartment == null)
                        throw new NotImplementedException("queryDepartment is null");
                }
                throw new NotImplementedException("Don't know where are you...");
            }
        }

        private void SetDepartmentName()
        {
            View.DepartmentName = CurrentDepartment.DepartmentName;
        }

        public void OnViewInitialized()
        {
            using (var z = _uow.Create()){
                SetDepartmentName();
                var tasks = _departmentService.GetTasksByDepartment(CurrentAccount, CurrentDepartment);
                M1(tasks);
                M2(tasks);
                M3(tasks);
                View.Executors = _executorsModels;
            }
        }

        private void M1(IQueryable<Task> tasks)
        {
            _executorsModels = new List<ExecutorsModel>{
                                                           tasks.ConvertToExecutorsModelItemAllTaskPresenter(
                                                               new TaskIsNew().IsSatisfiedBy(),
                                                               Translator.IsNew(), CurrentAccount)
                                                       };
        }

        private void M2(IQueryable<Task> tasks)
        {
            var executors = CurrentDepartment.Executors;
            foreach (var executor in executors){
                _executorsModels.Add(tasks.ConvertToExecutorsModelItemAllTaskPresenter(
                    (new TaskIsInProgress() & new HasExecutor(executor)).IsSatisfiedBy(),
                    Translator.InProgress(executor.FullName), CurrentAccount));
            }
        }

        private void M3(IQueryable<Task> tasks)
        {
            _executorsModels.Add(tasks.ConvertToExecutorsModelItemAllTaskPresenter(
                new TaskWaitingToClose().IsSatisfiedBy(), Translator.IsRequestClose(), CurrentAccount));
        }
    }
}